<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2018/6/15 0015
 * Time: 上午 10:28
 */

namespace app\socket\controller;

use app\common\model\Device;
use app\common\model\DeviceMap;
use app\common\model\Msg;
use think\facade\Log;
use think\worker\Server;
use Workerman\Lib\Timer;

class Worker extends Server
{
    protected $socket = 'tcp://0.0.0.0:8899';

    /**
     * 收到信息
     * @param $connection
     * @param $data
     */
    public function onMessage($connection, $data)
    {
        $cid = $connection->id;
        $device = Device::get(["device_me" => $data]);
        $d_m = new DeviceMap();
        $d_m_o = $d_m->where(["cid" => $cid])->find();
        if (!empty($device)) {//绑定设备
            if (empty($d_m_o)) {
                $d_m_o = new DeviceMap();
            }
            $d_m_o->device_id = $device->id;
            $d_m_o->cid = $cid;
            $d_m_o->save();
        }
        if (!empty($d_m_o)) {//记录消息
            $device_id = $d_m_o->device_id;
            $hex2str_data = self::hex2str($data);
            Log::info(  sprintf("device_id %s upload message %s",$device_id,$hex2str_data) );
//            Msg::create([
//                "pull_msg" => "",
//                "device_id" => $device_id,
//            ]);
        }
        $connection->send(self::hex2str("lyangakw"));
    }

    /**
     * 当连接建立时触发的回调函数
     * @param $connection
     */
    public function onConnect($connection)
    {

    }

    /**
     * 当连接断开时触发的回调函数
     * @param $connection
     */
    public function onClose($connection)
    {
        $cid = $connection->id;
        $d_m = new DeviceMap();
        $d_m_o = $d_m->where(["cid" => $cid])->delete();
    }

    /**
     * 当客户端的连接上发生错误时触发
     * @param $connection
     * @param $code
     * @param $msg
     */
    public function onError($connection, $code, $msg)
    {
        echo "error $code $msg\n";
    }

    /**
     * 每个进程启动
     * @param $worker
     */
    public function onWorkerStart($worker)
    {
        Timer::add(2, function () use ($worker) {
            $connections = $worker->connections;
            foreach ($connections as $connection) {
                Worker::pop_queue_msg($connection);
            }
        });
    }

    static function pop_queue_msg($connection)
    {
        $cid = $connection->id;
        $d_m = DeviceMap::get(["cid" => $cid]);
        if (!empty($d_m)) {
            $device_id = $d_m->device_id;
            $msg = new Msg();
            $msg_item = $msg->where("device_id", $device_id)
                ->where("push_msg", "<>", "")
                ->order("id asc")->find();
            if (!empty($msg_item)) {
                $push_msg = $msg_item->push_msg;
                $push_msg = self::str2hex($push_msg);
                Log::info(  sprintf(" send message %s to device_id %s",$push_msg,$device_id) );
                $connection->send($push_msg);
                $msg_item->delete();
            }
        }
    }

    static function hex2str($s)
    {
        $r = "";
        $hexes = array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f");
        for ($i = 0; $i < strlen($s); $i++)
            $r .= ($hexes [(ord($s{$i}) >> 4)] . $hexes [(ord($s{$i}) & 0xf)]);
        return $r;
    }

    static function str2hex($str)
    {
        $str = str_ireplace(" ","",$str);
        $str = strtolower($str);
        return hex2bin($str);
    }


}